package com.ssy.lingxi.marketing.serviceimpl.component.activity;

import com.ssy.lingxi.common.constant.marketing.ActivityTypeEnum;
import com.ssy.lingxi.marketing.model.bo.*;
import com.ssy.lingxi.marketing.model.constant.FullMoneyTypeEnum;
import com.ssy.lingxi.marketing.model.constant.FullQuantityTypeEnum;
import com.ssy.lingxi.marketing.utils.ValidatorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 活动预估到手价组件
 * @author yzc
 * @version 2.0.0
 * @date 2021/11/23
 */
@Slf4j
@Component
public class ActivityEstimatePriceComponent implements ActivityStrPool {


    /**
     * 处理商品详情的预估到手价(这个方法只预估, 特价, 直降, 折扣)
     * @param activityGoodsBOList 接口参数
     * @return 返回结果
     */
    public List<BigDecimal> calPromotionPriceList(List<ActivityGoodsDetailBO> activityGoodsBOList) {
        // 特价, 直降, 折扣
        List<Integer> activityTypeList = Arrays.asList(ActivityTypeEnum.SPECIAL_OFFER.getCode(), ActivityTypeEnum.PLUMMET.getCode(), ActivityTypeEnum.DISCOUNT.getCode());
        List<ActivityGoodsDetailBO> filterList = activityGoodsBOList.stream().filter(e -> activityTypeList.contains(e.getActivityBO().getActivityType())).collect(Collectors.toList());
        return filterList.stream().map(this::calEstimatePriceList).collect(Collectors.toList());
    }

    /**
     * @see #calEstimatePriceList
     * @param activityGoodsBOList 接口参数
     * @return 返回结果
     */
    public List<BigDecimal> calEstimatePriceList(List<ActivityGoodsDetailBO> activityGoodsBOList) {
        return activityGoodsBOList.stream().map(this::calEstimatePriceList).collect(Collectors.toList());
    }

    /**
     * 处理各种类型的活动商品预估到手价
     * @param activityGoodsBO 接口参数
     * @return 返回结果
     */
    public BigDecimal calEstimatePriceList(ActivityGoodsDetailBO activityGoodsBO) {
        // 活动类型
        Integer activityType = activityGoodsBO.getActivityBO().getActivityType();
        BigDecimal estimatePrice = BigDecimal.ZERO;
        if (ActivityTypeEnum.SPECIAL_OFFER.getCode().equals(activityType)) {
            // 特价促销
            estimatePrice = specialOfferPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.PLUMMET.getCode().equals(activityType)) {
            // 直降促销
            estimatePrice = plummetPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.DISCOUNT.getCode().equals(activityType)) {
            // 折扣促销
            estimatePrice = discountPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.FULL_QUANTITY.getCode().equals(activityType)) {
            // 满量促销
            estimatePrice = fullQuantityPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.FULL_MONEY.getCode().equals(activityType)) {
            // 满额促销
            estimatePrice = fullMoneyPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.GIVE.getCode().equals(activityType)) {
            // 赠送促销
            estimatePrice = givePrice(activityGoodsBO);
        } else if (ActivityTypeEnum.MORE_PIECE.getCode().equals(activityType)) {
            // 多件促销
            estimatePrice = morePiecePrice(activityGoodsBO);
        } else if (ActivityTypeEnum.COMBINATION.getCode().equals(activityType)) {
            // 组合促销
            estimatePrice = combinationPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.GROUP_PURCHASE.getCode().equals(activityType)) {
            // 拼团
            estimatePrice = groupPurchasePrice(activityGoodsBO);
        } else if (ActivityTypeEnum.LOTTERY.getCode().equals(activityType)) {
            // 抽奖 ignore
        } else if (ActivityTypeEnum.BARGAIN.getCode().equals(activityType)) {
            // 砍价
            estimatePrice = bargainPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.SEC_KILL.getCode().equals(activityType)) {
            // 秒杀
            estimatePrice = secKillPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.SWAP.getCode().equals(activityType)) {
            // 换购
            estimatePrice = swapPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.PRE_SALE.getCode().equals(activityType)) {
            // 预售
            estimatePrice = preSalePrice(activityGoodsBO);
        } else if (ActivityTypeEnum.SET_MEAL.getCode().equals(activityType)) {
            // 套餐
            estimatePrice = setMealPrice(activityGoodsBO);
        } else if (ActivityTypeEnum.ATTEMPT.getCode().equals(activityType)) {
            // 试用
            estimatePrice = attemptPrice(activityGoodsBO);
        }

        return estimatePrice;
    }

    /**
     * 特价
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal specialOfferPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getActivityPrice())) {
            log.error("特价活动商品, 预估到手价有误, activityPrice: {}", activityGoodsBO.getActivityPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getActivityPrice();
    }

    /**
     * 直降
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal plummetPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPrice())) {
            log.error("直降活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getPrice());
            return BigDecimal.ZERO;
        }

        if (!ValidatorUtil.isPositive(activityGoodsBO.getPlummetPrice())) {
            log.error("直降活动商品, 预估到手价有误, plummetPrice: {}", activityGoodsBO.getPlummetPrice());
            return BigDecimal.ZERO;
        }

        BigDecimal activityPrice = activityGoodsBO.getPrice().subtract(activityGoodsBO.getPlummetPrice());
        if (!ValidatorUtil.isPositive(activityPrice)) {
            log.error("直降活动商品, 预估到手价有误, activityPrice: {}", activityPrice);
            return BigDecimal.ZERO;
        }

        return activityPrice;
    }

    /**
     * 折扣
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal discountPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPrice())) {
            log.error("直降活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getPrice());
            return BigDecimal.ZERO;
        }

        if (!ValidatorUtil.isPositive(activityGoodsBO.getDiscount())) {
            log.error("直降活动商品, 预估到手价有误, discount: {}", activityGoodsBO.getDiscount());
            return BigDecimal.ZERO;
        }

        // 折扣存数据的为1-100, 要换算成小数
        BigDecimal discountRate = hundredToDecimal(activityGoodsBO.getDiscount());
        BigDecimal activityPrice = activityGoodsBO.getPrice().multiply(discountRate);
        if (!ValidatorUtil.isPositive(activityPrice)) {
            log.error("直降活动商品, 预估到手价有误, activityPrice: {}", activityPrice);
            return BigDecimal.ZERO;
        }

        return activityPrice;
    }

    /**
     * 满量
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal fullQuantityPrice(ActivityGoodsDetailBO activityGoodsBO) {
        FullQuantityBO fullQuantityBO = (FullQuantityBO) activityGoodsBO.getActivityBO().getActivityDefined();

        BigDecimal activityPrice = BigDecimal.ZERO;
        if (FullQuantityTypeEnum.REDUCTION.getCode().equals(fullQuantityBO.getType())) {
            /*BigDecimal unitMoneyReduction = fullQuantityBO.getLadderList().stream()
                    .map(ladderBO -> {
                        if (Objects.isNull(ladderBO.getKey()) || Objects.isNull(ladderBO.getValue())) {
                            return BigDecimal.ZERO;
                        }
                        return ladderBO.getValue();
                    })
                    .max(Comparator.comparing(e -> e))
                    .orElse(BigDecimal.ZERO);*/
            BigDecimal unitMoneyReduction = fullQuantityBO.getLadderList().stream()
                    .filter(ladderBO ->!Objects.isNull(ladderBO.getKey()) && !Objects.isNull(ladderBO.getValue()))
                    .map(e -> e.getValue().divide(e.getKey(),2, RoundingMode.HALF_UP))
                    .max(Comparator.comparing(e -> e)).orElse(BigDecimal.ZERO);
            BigDecimal subtractPrice = activityGoodsBO.getPrice().subtract(unitMoneyReduction);
            if (ValidatorUtil.isPositive(subtractPrice)) {
                activityPrice = subtractPrice;
            }

        } else if (FullQuantityTypeEnum.DISCOUNT.getCode().equals(fullQuantityBO.getType())) {
            BigDecimal discountRate = fullQuantityBO.getLadderList().stream()
                    .min(Comparator.comparing(FullQuantityBO.LadderBO::getValue))
                    .map(ladderBO -> hundredToDecimal(ladderBO.getValue()))
                    .orElse(BigDecimal.ZERO);

            BigDecimal discountPrice = activityGoodsBO.getPrice().multiply(discountRate);
            if (ValidatorUtil.isPositive(discountPrice)) {
                activityPrice = discountPrice;
            }

        }

        return activityPrice;
    }

    /**
     * 满额
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal fullMoneyPrice(ActivityGoodsDetailBO activityGoodsBO) {
        FullMoneyBO fullMoneyBO = (FullMoneyBO) activityGoodsBO.getActivityBO().getActivityDefined();

        BigDecimal activityPrice = BigDecimal.ZERO;
        if (FullMoneyTypeEnum.REDUCTION.getCode().equals(fullMoneyBO.getType())) {
            BigDecimal unitMoneyReduction = fullMoneyBO.getLadderList().stream()
                    .map(ladderBO -> {
                        if (Objects.isNull(ladderBO.getKey()) || Objects.isNull(ladderBO.getValue())) {
                            return BigDecimal.ZERO;
                        }
                        return ladderBO.getValue();
                    })
                    .max(Comparator.comparing(e -> e))
                    .orElse(BigDecimal.ZERO);

            BigDecimal subtractPrice = activityGoodsBO.getPrice().subtract(unitMoneyReduction);
            if (ValidatorUtil.isPositive(subtractPrice)) {
                activityPrice = subtractPrice;
            }

        } else if (FullMoneyTypeEnum.DISCOUNT.getCode().equals(fullMoneyBO.getType())) {
            BigDecimal discountRate = fullMoneyBO.getLadderList().stream()
                    .min(Comparator.comparing(FullMoneyBO.LadderBO::getValue))
                    .map(ladderBO -> hundredToDecimal(ladderBO.getValue()))
                    .orElse(BigDecimal.ZERO);

            BigDecimal discountPrice = activityGoodsBO.getPrice().multiply(discountRate);
            if (ValidatorUtil.isPositive(discountPrice)) {
                activityPrice = discountPrice;
            }

        }

        return activityPrice;
    }

    /**
     * 赠送
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal givePrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPrice())) {
            log.error("赠送活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getPrice();
    }

    /**
     * 多件
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal morePiecePrice(ActivityGoodsDetailBO activityGoodsBO) {
        MorePieceBO morePieceBO = (MorePieceBO) activityGoodsBO.getActivityBO().getActivityDefined();

        BigDecimal discountRate = morePieceBO.getLadderList().stream()
                .min(Comparator.comparing(MorePieceBO.LadderBO::getDiscount))
                .map(ladderBO -> hundredToDecimal(ladderBO.getDiscount()))
                .orElse(BigDecimal.ZERO);

        BigDecimal discountPrice = activityGoodsBO.getPrice().multiply(discountRate);
        if (!ValidatorUtil.isPositive(discountPrice)) {
            return BigDecimal.ZERO;
        }

        return discountPrice;
    }

    /**
     * 组合
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal combinationPrice(ActivityGoodsDetailBO activityGoodsBO) {
        CombinationBO combinationBO = (CombinationBO) activityGoodsBO.getActivityBO().getActivityDefined();

        if (Objects.isNull(combinationBO.getNum())
                || Objects.isNull(combinationBO.getPrice())) {
            return BigDecimal.ZERO;
        }

        BigDecimal unitNumPrice = div(combinationBO.getPrice(), BigDecimal.valueOf(combinationBO.getNum()));

        if (!ValidatorUtil.isPositive(unitNumPrice)) {
            return BigDecimal.ZERO;
        }

        return unitNumPrice;
    }

    /**
     * 拼团
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal groupPurchasePrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getActivityPrice())) {
            log.error("团购活动商品, 预估到手价有误, activityPrice: {}", activityGoodsBO.getActivityPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getActivityPrice();
    }

    /**
     * 砍价
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal bargainPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getActivityPrice())) {
            log.error("砍价活动商品, 预估到手价有误, activityPrice: {}", activityGoodsBO.getActivityPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getActivityPrice();
    }

    /**
     * 秒杀
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal secKillPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getActivityPrice())) {
            log.error("秒杀活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getActivityPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getActivityPrice();
    }

    /**
     * 换购
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal swapPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPrice())) {
            log.error("换购活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getPrice();
    }

    /**
     * 预售
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal preSalePrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPreSelPrice())) {
            log.error("预售活动商品, 预估到手价有误, preSelPrice: {}", activityGoodsBO.getPreSelPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getPreSelPrice();
    }

    /**
     * 套餐
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal setMealPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPrice())) {
            log.error("换购活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getPrice();
    }

    /**
     * 试用
     *
     * @param activityGoodsBO 活动商品
     * @return 返回结果
     */
    private BigDecimal attemptPrice(ActivityGoodsDetailBO activityGoodsBO) {
        if (!ValidatorUtil.isPositive(activityGoodsBO.getPrice())) {
            log.error("试用活动商品, 预估到手价有误, productPrice: {}", activityGoodsBO.getPrice());
            return BigDecimal.ZERO;
        }

        return activityGoodsBO.getPrice();
    }
}
